import json, datetime
from django.core.paginator import Paginator
from django_redis import get_redis_connection
from homes.models import House, Area, HouseImage
from datetime import datetime
from myhome.utils import constants
# Create your views here.
from myhome.utils.checking_image import image_file
from myhome.utils.decorators import login_required
from order.models import Order
import logging
from django.shortcuts import render
from django.views import View
from django.http import JsonResponse
from .models import Area, House, Facility
from django.utils.decorators import method_decorator
# 处理图片
from fdfs_client.client import Fdfs_client
from PIL import Image
from io import BytesIO
from django.conf import settings
from django.db.models import Q

logger = logging.getLogger('django')


class HomePageView(View):

    # 首页房屋推荐
    def get(self, request):
        house_list = House.objects.order_by('-order_count')[:5]

        data = []

        for house in house_list:
            data.append({
                'house_id': house.id,
                'img_url': settings.FDFS_URL + house.index_image_url,
                'title': house.title
            })

        return JsonResponse({
            'errno': 0,
            'errmsg': 'ok',
            'data': data
        })


class HomeSearchView(View):
    # 房屋数据搜索

    def get(self, request):

        # 获取请求参数
        aid = request.GET.get('aid')  # 区域id
        sd = request.GET.get('sd')  # start_day 开始日期
        ed = request.GET.get('ed')  # end_day 结束日期
        sk = request.GET.get('sk')  # sort_key 排序方式
        p = request.GET.get('p')  # page 页数, 不传默认1

        # 校验参数
        if not p.isdigit():
            return JsonResponse({
                'code': 400,
                'errmsg': '参数类型错误'
            })

        # redis_conn = get_redis_connection("house_cache")
        # try:
        #     redis_key = "houses_%s_%s_%s_%s" % (aid, sd, ed, sk)
        #     data = redis_conn.hget(redis_key, p)
        #     if data:
        #         return JsonResponse({"errno": 'NO', "errmsg": "OK", "data": json.loads(data)})
        # except Exception as e:
        #     logger.error(e)

        # 选取时间 -- 默认为0
        start_date = None
        end_date = None
        if sd:
            start_date = datetime.strptime(sd, '%Y-%m-%d')
        if ed:
            end_date = datetime.strptime(ed, '%Y-%m-%d')

        # 判断选取时间
        if start_date and end_date:
            if start_date > end_date:
                return JsonResponse({
                    'code': 400,
                    'errmsg': '时间选择错误'
                })

        # 每个房屋的查询
        # 判断 区域是否存在
        # 定义一个字典 -- 过滤出区域
        filters = {}
        if aid:
            # 加入到大字典
            filters['area_id'] = aid

        # 获取正确的房屋id
        # 获取订单中的房屋编号

        # 定义数组保存冲突的订单
        if start_date and end_date:
            # 如果订单的开始时间 < 结束时间 and 订单的结束时间 > 开始时间
            conflict_order = Order.objects.filter(begin_date__lt=end_date, end_date__gt=start_date)
        elif start_date:
            # 订单的结束时间 > 开始时间
            conflict_order = Order.objects.filter(end_date__gt=start_date)
        elif end_date:
            # 订单的开始时间 < 结束时间
            conflict_order = Order.objects.filter(begin_date__lt=end_date)
        else:
            conflict_order = []

        # 取到冲突订单的房屋id
        conflict_house_id = [order.house_id for order in conflict_order]
        # 添加条件:查询出来的房屋不包括冲突订单中的房屋
        houses = House.objects.filter(Q(**filters) & ~Q(id__in=conflict_house_id))

        # 查询排序
        my_dict = {"booking": "-order_count", "price-inc": "price", "price-des": "-price", "new": "-create_time"}
        house_query = houses.order_by(my_dict[sk])

        # 分页 -- # 房屋列表页面每页显示条目数
        paginator = Paginator(house_query, constants.HOUSE_LIST_PAGE_CAPACITY)
        # 获取当前页对象
        page_houses = paginator.page(p)
        # 获取总页数
        total_page = paginator.num_pages

        # 构建参数
        houses = []
        for house in page_houses:
            houses.append({
                'address': house.address,
                'area_name': house.area.name,
                'ctime': house.create_time.strftime('%Y-%m-%d'),
                'house_id': house.id,
                'img_url': settings.FDFS_URL + house.index_image_url,
                'order_count': house.order_count,
                'price': house.price,
                'room_count': house.room_count,
                'title': house.title,
                'user_avatar': settings.FDFS_URL + house.user.avatar
            })

        return JsonResponse({
            'errno': 0,
            'errmsg': 'ok',
            'data': {
                'total_page': total_page,
                'houses': houses
            }
        })

    """发布房源"""

    @method_decorator(login_required)
    def post(self, request):
        # 1.获取用户
        user = request.user
        # 获取参数
        data_dict = json.loads(request.body.decode())
        title = data_dict.get('title')
        price = data_dict.get('price')
        address = data_dict.get('address')
        area_id = data_dict.get('area_id')
        room_count = data_dict.get('room_count')
        acreage = data_dict.get('acreage')
        unit = data_dict.get('unit')
        capacity = data_dict.get('capacity')
        beds = data_dict.get('beds')
        deposit = data_dict.get('deposit')
        min_days = data_dict.get('min_days')
        max_days = data_dict.get('max_days')

        # 验证参数
        if not all([title, price, address, area_id, room_count, acreage, unit, capacity, beds, deposit, min_days,
                    max_days]):
            return JsonResponse({'errno': 4103, 'errmsg': '参数缺失'})

        try:
            price = int(float(price) * 100)
            deposit = int(float(deposit) * 100)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4103, "errmsg": "参数错误"})

        try:
            area = Area.objects.get(id=area_id)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4103, "errmsg": "地址不存在"})

        # 保存到数据库
        try:
            house = House.objects.create(
                user=request.user,
                title=title,
                price=price,
                area_id=area_id,
                address=address,
                room_count=room_count,
                acreage=acreage,
                unit=unit,
                capacity=capacity,
                beds=beds,
                deposit=deposit,
                min_days=min_days,
                max_days=max_days)
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 4004, 'errmsg': '保存失败'})

        # 设置设施信息
        try:
            facility_ids = data_dict.get('facility')
            if facility_ids:
                facilities = Facility.objects.filter(id__in=facility_ids)
                for facility in facilities:
                    house.facility.add(facility)
        except Exception as e:
            return JsonResponse({'errno': 4004, 'errmsg': '保存失败'})

        # 构建返回结果

        return JsonResponse({"errno": "0", "errmsg": "发布成功", "data": {"house_id": house.id}})


class HouseInfoView(View):
    # 房屋详情页
    def get(self, request, house_id):

        # 获取房子信息
        house = House.objects.get(pk=house_id)

        # 判断用户是否登录
        if not request.user.is_authenticated:
            request.user.id = None

        # 先从redis缓存中取
        # redis_conn = get_redis_connection("house_cache")

        # house_dict = redis_conn.get('house_info_' + house_id)
        # 评论
        orders = Order.objects.filter(house_id=house_id, comment__isnull=False,
                                      status=Order.ORDER_STATUS["COMPLETE"]).order_by('-update_time')[:10]
        comments = []
        for order in orders:
            comments.append({
                "comment": order.comment,
                "ctime": order.update_time.strftime('%Y-%m-%d'),
                "user_name": order.user.username
            })

        images = HouseImage.objects.filter(house_id=house_id)
        house_dict = {
            'acreage': house.acreage,
            'address': house.address,
            'beds': house.beds,
            'capacity': house.capacity,
            'comments': comments,
            'deposit': house.deposit,
            'facilities': [facility.id for facility in house.facility.all()],
            'hid': house.id,
            'img_urls': [settings.FDFS_URL + image.url for image in images],
            'max_days': house.max_days,
            'min_days': house.min_days,
            'price': house.price,
            'room_count': house.room_count,
            'title': house.title,
            'unit': house.unit,
            'user_avatar': settings.FDFS_URL + request.user.avatar,
            'user_id': house.user.id,
            'user_name': house.user.username,
        }

        data = {
            'house': house_dict,
            'user_id': request.user.id
        }

        return JsonResponse({
            'errno': 0,
            'errmsg': 'ok',
            'data': data
        })

    """发布房源"""

    def post(self, request):
        # 1.获取用户
        user = request.user
        # 获取参数
        data_dict = json.loads(request.body.decode())
        title = data_dict.get('title')
        price = data_dict.get('price')
        address = data_dict.get('address')
        area_id = data_dict.get('area_id')
        room_count = data_dict.get('room_count')
        acreage = data_dict.get('acreage')
        unit = data_dict.get('unit')
        capacity = data_dict.get('capacity')
        beds = data_dict.get('beds')
        deposit = data_dict.get('deposit')
        min_days = data_dict.get('min_days')
        max_days = data_dict.get('max_days')

        # 验证参数
        if not all([title, price, address, area_id, room_count, acreage, unit, capacity, beds, deposit, min_days,
                    max_days]):
            return JsonResponse({'errno': 4103, 'errmsg': '参数缺失'})

        try:
            price = int(float(price) * 100)
            deposit = int(float(deposit) * 100)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4103, "errmsg": "参数错误"})

        try:
            area = Area.objects.get(id=area_id)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4103, "errmsg": "地址不存在"})

        # 保存到数据库
        try:
            house = House.objects.create(
                title=title,
                price=price,
                area_id=area_id,
                address=address,
                room_count=room_count,
                acreage=acreage,
                unit=unit,
                capacity=capacity,
                beds=beds,
                deposit=deposit,
                min_days=min_days,
                max_days=max_days)
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 4004, 'errmsg': '保存失败'})

        # 设置设施信息
        try:
            facility_ids = data_dict.get('facility')
            if facility_ids:
                facilities = Facility.objects.filter(id__in=facility_ids)
                for facility in facilities:
                    house.facility.add(facility)
        except Exception as e:
            return JsonResponse({'errno': 4004, 'errmsg': '保存失败'})

        # 构建返回结果

        return JsonResponse({"errno": "0", "errmsg": "发布成功", "data": {"house_id": 1}})


class AreaView(View):
    """城区列表"""

    def get(self, request):
        # 查询数据
        area_model_list = Area.objects.all()

        data = []

        for area in area_model_list:
            data.append({
                'aid': area.id,
                'aname': area.name
            })

        return JsonResponse({
            'errno': 0,
            'errmsg': 'ok',
            'data': data
        })


class HouseImageView(View):
    """
    房源图片上传
    """

    @method_decorator(login_required)
    def post(self, request, house_id):
        house_image = request.FILES.get("house_image")

        if not house_image:
            return JsonResponse({'errno': 4103, 'errmsg': '参数错误'})

        if not image_file(house_image):
            return JsonResponse({'errno': 4103, 'errmsg': '参数错误'})

        try:
            house = House.objects.get(id=house_id)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4103, "errmsg": "该房间不存在"})
        # 图片大小处理
        house_image = house_image.file.getvalue()
        image = Image.open(BytesIO(house_image))
        house_IMG = image.resize((364, 312), Image.ANTIALIAS)
        img = BytesIO()
        house_IMG.save(img, format='JPEG')
        img = img.getvalue()

        client = Fdfs_client('myhome/utils/fastdfs/client.conf')
        ret = client.upload_by_buffer(img)
        url_end = ret.get('Remote file_id')
        url_end = '/'.join(url_end.split('\\'))
        try:
            house = House.objects.get(id=house_id)
            url = settings.FDFS_URL + url_end
            if not house.index_image_url:
                house.index_image_url = url_end
                house.save()
            HouseImage.objects.create(url=url_end, house=house)
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': '4103', 'errmsg': '上传失败'})
        return JsonResponse({
            'errno': '0',
            'errmsg': 'ok',
            'data': {'url': url}
        })


class UserHouseView(View):
    """
    显示房屋列表
    """

    @method_decorator(login_required)
    def get(self, request):
        user = request.user

        houses = House.objects.filter(user=user)

        house_dict = []

        for house in houses:
            house_dict.append({
                'address': house.address,
                'area_name': house.area.name,
                'ctime': house.create_time.strftime('%Y-%m-%d'),
                'house_id': house.pk,
                'img_url': settings.FDFS_URL + house.index_image_url,
                'order_count': house.order_count,
                'price': house.price,
                'room_count': house.room_count,
                'title': house.title,
                'user_avatar': house.user.avatar
            })

        return JsonResponse({"errno": 0, "errmsg": "成功", "data": {'houses': house_dict}})
